package com.atguigu.tingshu.album.listener;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.common.constant.RabbitConstant;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.vo.album.TrackStatMqVo;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class AlbumMqListener {


    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    TrackInfoService trackInfoService;
    @Autowired
    AlbumInfoService albumInfoService;
    @RabbitListener(
            bindings = @QueueBinding(
                    value = @Queue(value = "maxwell.queue"),
                    exchange = @Exchange(value = "maxwell.exchange" , type = ExchangeTypes.TOPIC),
                    key = {"tingshu_album.album_info"} // * 通配一级  # 通配多级
            )
    )
    public void maxwellListener(Channel channel , Message message,
                                String json) throws IOException {


        try {
            System.out.println("routingKey: "+message.getMessageProperties().getReceivedRoutingKey());
            System.out.println("json:"+json);
            JSONObject jsonObject = JSONObject.parseObject(json, JSONObject.class);
//            System.out.println(jsonObject.get("data"));
//            System.out.println(jsonObject.get("data").getClass().getName());
//            String type = jsonObject.get("type").toString();
//            if("delete".equalsIgnoreCase(type)){
//                //删除操作
//            }else if()
            JSONObject albumInfo = (JSONObject) jsonObject.get("data");
            long albumId = Long.parseLong(albumInfo.get("id").toString());
            albumInfoService.deleteCacheAsync("album:cache:["+albumId+"]");
            //同步数据
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            if(message.getMessageProperties().isRedelivered()){
                //丢弃消息
                channel.basicReject( message.getMessageProperties().getDeliveryTag(),false);
                throw new GuiguException(ResultCodeEnum.DATA_ERROR);
            }else{
                //第一次消费异常时需要重试，可以删除redis幂等性token
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),
                        false,true);
            }
        }

    }
    @RabbitListener(
            bindings = @QueueBinding(
                    value = @Queue(value = RabbitConstant.TRACK_STAT_QUEUE),
                    exchange = @Exchange(value = RabbitConstant.ALBUM_EXCHANGE , type = ExchangeTypes.TOPIC),
                    key = {RabbitConstant.TRACK_STAT_RK}
            )
    )
    public void updateTrackStat(Channel channel , Message message,
                                TrackStatMqVo vo) throws IOException {
        //幂等性
        String businessNo = vo.getBusinessNo();
        String key = RedisConstant.TRACK_STAT_IDEM + businessNo;
        try {
            Boolean flag = redisTemplate.opsForValue().setIfAbsent(key, 1, 10, TimeUnit.MINUTES);
            if(flag){
                //第一次消费消息：更新专辑和声音的播放量
                trackInfoService.updateTrackStat(vo);

            }

            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            if(message.getMessageProperties().isRedelivered()){
                log.error("专辑声音播放量更新异常，声音id:{}" , vo.getTrackId());
                //丢弃消息
                channel.basicReject( message.getMessageProperties().getDeliveryTag(),false);
                throw new GuiguException(ResultCodeEnum.DATA_ERROR);
            }else{
                //第一次消费异常时需要重试，可以删除redis幂等性token
                redisTemplate.delete(key);
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),
                        false,true);
            }
        }
    }
}
